{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "lTR76MnbHlMF"
   },
   "source": [
    "# Llama Pack - Neo4j 查询引擎\n",
    "本 Llama Pack 创建了一个 Neo4j 知识图谱查询引擎，并执行其 `query` 函数。此包提供了为 Neo4j 知识图谱创建多种类型的查询引擎的选项，包括：\n",
    "\n",
    "* 知识图谱基于向量的实体检索（如果没有提供查询引擎类型选项，则为默认选项）\n",
    "* 知识图谱基于关键词的实体检索\n",
    "* 知识图谱混合实体检索\n",
    "* 原始向量索引检索\n",
    "* 自定义组合查询引擎（向量相似性 + 知识图谱实体检索）\n",
    "* KnowledgeGraphQueryEngine\n",
    "* KnowledgeGraphRAGRetriever\n",
    "\n",
    "对于这个笔记本，我们将加载一个关于古食饮食的维基百科页面到 Neo4j 知识图谱中，并执行查询。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 安装了必要的库\n",
    "\n",
    "- `llama_index`：将大语言模型和外部数据连接在一起的工具\n",
    "- `neo4j`：用于存储采集的数据，支持实体和属性等关系查询\n",
    "- `llama_hub`：一个社区驱动的预打包模块中心，可以使用它来启动 LLM 应用程序\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "id": "gZhtMcUkhCRn"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: llama_index in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (0.9.21)\n",
      "Requirement already satisfied: llama_hub in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (0.0.64)\n",
      "Requirement already satisfied: neo4j in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (5.15.0)\n",
      "Requirement already satisfied: SQLAlchemy>=1.4.49 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from SQLAlchemy[asyncio]>=1.4.49->llama_index) (2.0.23)\n",
      "Requirement already satisfied: aiohttp<4.0.0,>=3.8.6 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (3.9.1)\n",
      "Requirement already satisfied: beautifulsoup4<5.0.0,>=4.12.2 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (4.12.2)\n",
      "Requirement already satisfied: dataclasses-json in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (0.6.3)\n",
      "Requirement already satisfied: deprecated>=1.2.9.3 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (1.2.14)\n",
      "Requirement already satisfied: fsspec>=2023.5.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (2023.12.2)\n",
      "Requirement already satisfied: httpx in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (0.26.0)\n",
      "Requirement already satisfied: nest-asyncio<2.0.0,>=1.5.8 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (1.5.8)\n",
      "Requirement already satisfied: nltk<4.0.0,>=3.8.1 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (3.8.1)\n",
      "Requirement already satisfied: numpy in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (1.26.2)\n",
      "Requirement already satisfied: openai>=1.1.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (1.21.2)\n",
      "Requirement already satisfied: pandas in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (2.1.4)\n",
      "Requirement already satisfied: requests>=2.31.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (2.31.0)\n",
      "Requirement already satisfied: tenacity<9.0.0,>=8.2.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (8.2.3)\n",
      "Requirement already satisfied: tiktoken>=0.3.3 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (0.5.2)\n",
      "Requirement already satisfied: typing-extensions>=4.5.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (4.9.0)\n",
      "Requirement already satisfied: typing-inspect>=0.8.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_index) (0.9.0)\n",
      "Requirement already satisfied: html2text in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_hub) (2020.1.16)\n",
      "Requirement already satisfied: psutil in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_hub) (5.9.7)\n",
      "Requirement already satisfied: pyaml<24.0.0,>=23.9.7 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_hub) (23.12.0)\n",
      "Requirement already satisfied: retrying in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from llama_hub) (1.3.4)\n",
      "Requirement already satisfied: pytz in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from neo4j) (2023.3.post1)\n",
      "Requirement already satisfied: attrs>=17.3.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.6->llama_index) (23.1.0)\n",
      "Requirement already satisfied: multidict<7.0,>=4.5 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.6->llama_index) (6.0.4)\n",
      "Requirement already satisfied: yarl<2.0,>=1.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.6->llama_index) (1.9.4)\n",
      "Requirement already satisfied: frozenlist>=1.1.1 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.6->llama_index) (1.4.1)\n",
      "Requirement already satisfied: aiosignal>=1.1.2 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from aiohttp<4.0.0,>=3.8.6->llama_index) (1.3.1)\n",
      "Requirement already satisfied: soupsieve>1.2 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from beautifulsoup4<5.0.0,>=4.12.2->llama_index) (2.5)\n",
      "Requirement already satisfied: wrapt<2,>=1.10 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from deprecated>=1.2.9.3->llama_index) (1.16.0)\n",
      "Requirement already satisfied: click in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from nltk<4.0.0,>=3.8.1->llama_index) (8.1.7)\n",
      "Requirement already satisfied: joblib in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from nltk<4.0.0,>=3.8.1->llama_index) (1.3.2)\n",
      "Requirement already satisfied: regex>=2021.8.3 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from nltk<4.0.0,>=3.8.1->llama_index) (2023.12.25)\n",
      "Requirement already satisfied: tqdm in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from nltk<4.0.0,>=3.8.1->llama_index) (4.66.1)\n",
      "Requirement already satisfied: anyio<5,>=3.5.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from openai>=1.1.0->llama_index) (4.2.0)\n",
      "Requirement already satisfied: distro<2,>=1.7.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from openai>=1.1.0->llama_index) (1.9.0)\n",
      "Requirement already satisfied: pydantic<3,>=1.9.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from openai>=1.1.0->llama_index) (2.5.3)\n",
      "Requirement already satisfied: sniffio in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from openai>=1.1.0->llama_index) (1.3.0)\n",
      "Requirement already satisfied: certifi in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from httpx->llama_index) (2023.11.17)\n",
      "Requirement already satisfied: httpcore==1.* in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from httpx->llama_index) (1.0.2)\n",
      "Requirement already satisfied: idna in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from httpx->llama_index) (3.6)\n",
      "Requirement already satisfied: h11<0.15,>=0.13 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from httpcore==1.*->httpx->llama_index) (0.14.0)\n",
      "Requirement already satisfied: PyYAML in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from pyaml<24.0.0,>=23.9.7->llama_hub) (6.0.1)\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from requests>=2.31.0->llama_index) (3.3.2)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from requests>=2.31.0->llama_index) (2.1.0)\n",
      "Requirement already satisfied: greenlet!=0.4.17 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from SQLAlchemy[asyncio]>=1.4.49->llama_index) (3.0.3)\n",
      "Requirement already satisfied: mypy-extensions>=0.3.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from typing-inspect>=0.8.0->llama_index) (1.0.0)\n",
      "Requirement already satisfied: marshmallow<4.0.0,>=3.18.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from dataclasses-json->llama_index) (3.20.1)\n",
      "Requirement already satisfied: python-dateutil>=2.8.2 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from pandas->llama_index) (2.8.2)\n",
      "Requirement already satisfied: tzdata>=2022.1 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from pandas->llama_index) (2023.3)\n",
      "Requirement already satisfied: six>=1.7.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from retrying->llama_hub) (1.16.0)\n",
      "Requirement already satisfied: packaging>=17.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from marshmallow<4.0.0,>=3.18.0->dataclasses-json->llama_index) (23.2)\n",
      "Requirement already satisfied: annotated-types>=0.4.0 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from pydantic<3,>=1.9.0->openai>=1.1.0->llama_index) (0.6.0)\n",
      "Requirement already satisfied: pydantic-core==2.14.6 in /Users/minp/miniconda3/envs/llamaindex_nebulagraph_phillies/lib/python3.11/site-packages (from pydantic<3,>=1.9.0->openai>=1.1.0->llama_index) (2.14.6)\n",
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    }
   ],
   "source": [
    "%pip install llama_index llama_hub neo4j"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 调整输出日志配置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "id": "9WMxhw2Yjpjs"
   },
   "outputs": [],
   "source": [
    "import os, logging, sys\n",
    "\n",
    "logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "y8B2WvxtNs0V"
   },
   "source": [
    "## 加载数据\n",
    "\n",
    "加载维基百科中关于古法饮食的页面。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "2xC1ThySNsAY",
    "outputId": "a96de42a-ace1-4b36-f3ab-a29d6bd921ad"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): llamahub.ai:443\n",
      "DEBUG:urllib3.connectionpool:https://llamahub.ai:443 \"POST /api/analytics/downloads HTTP/1.1\" 200 63\n",
      "DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): 127.0.0.1:7890\n",
      "DEBUG:urllib3.connectionpool:http://127.0.0.1:7890 \"GET http://en.wikipedia.org/w/api.php?prop=info%7Cpageprops&inprop=url&ppprop=disambiguation&redirects=&titles=Paleolithic+diet&format=json&action=query HTTP/1.1\" 301 0\n",
      "DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): en.wikipedia.org:443\n",
      "DEBUG:urllib3.connectionpool:https://en.wikipedia.org:443 \"GET /w/api.php?prop=info%7Cpageprops&inprop=url&ppprop=disambiguation&redirects=&titles=Paleolithic+diet&format=json&action=query HTTP/1.1\" 200 477\n",
      "DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): 127.0.0.1:7890\n",
      "DEBUG:urllib3.connectionpool:http://127.0.0.1:7890 \"GET http://en.wikipedia.org/w/api.php?prop=extracts%7Crevisions&explaintext=&rvprop=ids&titles=Paleolithic+diet&format=json&action=query HTTP/1.1\" 301 0\n",
      "DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): en.wikipedia.org:443\n",
      "DEBUG:urllib3.connectionpool:https://en.wikipedia.org:443 \"GET /w/api.php?prop=extracts%7Crevisions&explaintext=&rvprop=ids&titles=Paleolithic+diet&format=json&action=query HTTP/1.1\" 200 None\n",
      "Loaded 1 documents\n"
     ]
    }
   ],
   "source": [
    "from llama_index import download_loader\n",
    "\n",
    "WikipediaReader = download_loader(\"WikipediaReader\")\n",
    "loader = WikipediaReader()\n",
    "documents = loader.load_data(pages=['Paleolithic diet'], auto_suggest=False)\n",
    "print(f'Loaded {len(documents)} documents')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "icH9lDT7LAQH"
   },
   "source": [
    "## 下载并初始化软件包"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 使用 OpenAI 相关配置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# from llama_index.llama_pack import download_llama_pack\n",
    "\n",
    "# os.environ['OPENAI_API_KEY'] = \"sk-xxx\"\n",
    "\n",
    "# # download and install dependencies\n",
    "# Neo4jQueryEnginePack = download_llama_pack(\n",
    "#   \"Neo4jQueryEnginePack\", \"./neo4j_pack\"\n",
    "# )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 使用 AuzreOpenAI 相关配置（当前项目的默认使用配置）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "id": "-SOCDPS32GM7"
   },
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n",
    "from neo4j_pack.base import Neo4jQueryEnginePack\n",
    "# neo4j_pack.base 配置对应的 Auzre 账号\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Neo4j 安装与配置"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 安装 neo4j 服务\n",
    "```shell\n",
    "docker run -d -p 7474:7474 -p 7687:7687 --name neo4j-apoc -e NEO4J_apoc_export_file_enabled=true -e NEO4J_apoc_import_file_enabled=true -e NEO4J_apoc_import_file_use__neo4j__config=true -e NEO4J_AUTH=neo4j/pleaseletmein -e NEO4J_PLUGINS=\\[\\\"apoc\\\"\\] neo4j:latest\n",
    "```\n",
    "- username：neo4j\n",
    "- password：pleaseletmein\n",
    "- url：bolt://127.0.0.1:7687\n",
    "- database：username：neo4j"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "l1oGbRIPN3RS"
   },
   "source": [
    "### 配置 Neo4j 信息\n",
    "Neo4j 的证书存储在项目根目录下的 `credentials.json` 中，加载 json 并提取证书详细信息。\n",
    "请开 [credentials.json](./credentials.json) ，配置安装的 Neo4j 服务时的指定的账号信息\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "id": "KO0oa4GJ0_Gx"
   },
   "outputs": [],
   "source": [
    "import json\n",
    "\n",
    "# get Neo4j credentials (assume it's stored in credentials.json)\n",
    "with open('credentials.json') as f:\n",
    "  neo4j_connection_params = json.load(f)\n",
    "  username = neo4j_connection_params['username']\n",
    "  password = neo4j_connection_params['password']\n",
    "  url = neo4j_connection_params['url']\n",
    "  database = neo4j_connection_params['database']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "vTUiXf5xLRRO"
   },
   "source": [
    "以下是 `Neo4jQueryEnginePack`的构造方式。你可以从 `Neo4jQueryEngineType` 传入 `query_engine_type` 来构建 `Neo4jQueryEnginePack`。下面的代码片段展示了一个知识图谱（KG）关键词查询引擎。如果没有定义 `query_engine_type`，它默认为基于KG向量的实体检索。\n",
    "\n",
    "`Neo4jQueryEngineType` 是一个枚举类型，包含多种查询引擎类型，如下所示。你可以传入其中任何一个查询引擎类型来构建 `Neo4jQueryEnginePack`。\n",
    "\n",
    "\n",
    "```\n",
    "class Neo4jQueryEngineType(str, Enum):\n",
    "    \"\"\"Neo4j query engine type\"\"\"\n",
    "\n",
    "    KG_KEYWORD = \"keyword\"\n",
    "    KG_HYBRID = \"hybrid\"\n",
    "    RAW_VECTOR = \"vector\"\n",
    "    RAW_VECTOR_KG_COMBO = \"vector_kg\"\n",
    "    KG_QE = \"KnowledgeGraphQueryEngine\"\n",
    "    KG_RAG_RETRIEVER = \"KnowledgeGraphRAGRetriever\"\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/"
    },
    "id": "MldEbU3xz3Yk",
    "outputId": "062e4b27-dd9c-425c-9d32-b889d2fe55b5"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "DEBUG:neo4j:[#0000]  _: <POOL> created, direct address IPv4Address(('127.0.0.1', 7687))\n",
      "DEBUG:neo4j:[#0000]  _: <POOL> acquire direct connection, access_mode='READ', database=None\n",
      "DEBUG:neo4j:[#0000]  _: <POOL> trying to hand out new connection\n",
      "DEBUG:neo4j:[#0000]  _: <RESOLVE> in: 127.0.0.1:7687\n",
      "DEBUG:neo4j:[#0000]  _: <RESOLVE> dns resolver out: 127.0.0.1:7687\n",
      "DEBUG:neo4j:[#0000]  C: <OPEN> 127.0.0.1:7687\n",
      "DEBUG:neo4j:[#FA11]  C: <MAGIC> 0x6060B017\n",
      "DEBUG:neo4j:[#FA11]  C: <HANDSHAKE> 0x00040405 0x00020404 0x00000104 0x00000003\n",
      "DEBUG:neo4j:[#FA11]  S: <HANDSHAKE> 0x00000405\n",
      "DEBUG:neo4j:[#FA11]  C: HELLO {'user_agent': 'neo4j-python/5.15.0 Python/3.11.6-final-0 (darwin)', 'bolt_agent': {'product': 'neo4j-python/5.15.0', 'platform': 'Darwin 23.4.0; arm64', 'language': 'Python/3.11.6-final-0', 'language_details': 'CPython; 3.11.6-final-0 (main, Oct  3 2023 10:37:07) [Clang 15.0.7 ]'}}\n",
      "DEBUG:neo4j:[#FA11]  _: <CONNECTION> client state: CONNECTED > AUTHENTICATION\n",
      "DEBUG:neo4j:[#FA11]  C: LOGON {'scheme': 'basic', 'principal': 'neo4j', 'credentials': '*******'}\n",
      "DEBUG:neo4j:[#FA11]  _: <CONNECTION> client state: AUTHENTICATION > READY\n",
      "DEBUG:neo4j:[#FA11]  S: SUCCESS {'server': 'Neo4j/5.15.0', 'connection_id': 'bolt-84', 'hints': {'connection.recv_timeout_seconds': 120}}\n",
      "DEBUG:neo4j:[#FA11]  _: <CONNECTION> server state: CONNECTED > AUTHENTICATION\n",
      "DEBUG:neo4j:[#FA11]  S: SUCCESS {}\n",
      "DEBUG:neo4j:[#FA11]  _: <CONNECTION> server state: AUTHENTICATION > READY\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> released bolt-84\n",
      "DEBUG:neo4j:[#0000]  _: <POOL> acquire direct connection, access_mode='WRITE', database='neo4j'\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> picked existing connection bolt-84\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> checked re_auth auth=None updated=False force=False\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> handing out existing connection\n",
      "DEBUG:neo4j:[#FA11]  C: RUN '\\nCALL apoc.meta.data()\\nYIELD label, other, elementType, type, property\\nWHERE NOT type = \"RELATIONSHIP\" AND elementType = \"node\"\\nWITH label AS nodeLabels, collect({property:property, type:type}) AS properties\\nRETURN {labels: nodeLabels, properties: properties} AS output\\n\\n' {} {'db': 'neo4j'}\n",
      "DEBUG:neo4j:[#FA11]  _: <CONNECTION> client state: READY > STREAMING\n",
      "DEBUG:neo4j:[#FA11]  C: PULL {'n': 1000}\n",
      "DEBUG:neo4j:[#FA11]  S: SUCCESS {'t_first': 56, 'fields': ['output']}\n",
      "DEBUG:neo4j:[#FA11]  _: <CONNECTION> server state: READY > STREAMING\n",
      "DEBUG:neo4j:[#FA11]  S: RECORD * 1\n",
      "DEBUG:neo4j:[#FA11]  S: RECORD * 1\n",
      "DEBUG:neo4j:[#FA11]  S: RECORD * 1\n",
      "DEBUG:neo4j:[#FA11]  S: RECORD * 1\n",
      "DEBUG:neo4j:[#FA11]  S: SUCCESS {'bookmark': 'FB:kcwQ6StP4FHeSWOIpT0EVLaCoBuQ', 'type': 'r', 't_last': 2, 'db': 'neo4j'}\n",
      "DEBUG:neo4j:[#FA11]  _: <CONNECTION> server state: STREAMING > READY\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> released bolt-84\n",
      "DEBUG:neo4j:[#0000]  _: <POOL> acquire direct connection, access_mode='WRITE', database='neo4j'\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> picked existing connection bolt-84\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> checked re_auth auth=None updated=False force=False\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> handing out existing connection\n",
      "DEBUG:neo4j:[#FA11]  C: RUN '\\nCALL apoc.meta.data()\\nYIELD label, other, elementType, type, property\\nWHERE NOT type = \"RELATIONSHIP\" AND elementType = \"relationship\"\\nWITH label AS nodeLabels, collect({property:property, type:type}) AS properties\\nRETURN {type: nodeLabels, properties: properties} AS output\\n' {} {'db': 'neo4j'}\n",
      "DEBUG:neo4j:[#FA11]  C: PULL {'n': 1000}\n",
      "DEBUG:neo4j:[#FA11]  S: SUCCESS {'t_first': 16, 'fields': ['output']}\n",
      "DEBUG:neo4j:[#FA11]  _: <CONNECTION> server state: READY > STREAMING\n",
      "DEBUG:neo4j:[#FA11]  S: SUCCESS {'bookmark': 'FB:kcwQ6StP4FHeSWOIpT0EVLaCoBuQ', 'type': 'r', 't_last': 1, 'db': 'neo4j'}\n",
      "DEBUG:neo4j:[#FA11]  _: <CONNECTION> server state: STREAMING > READY\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> released bolt-84\n",
      "DEBUG:neo4j:[#0000]  _: <POOL> acquire direct connection, access_mode='WRITE', database='neo4j'\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> picked existing connection bolt-84\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> checked re_auth auth=None updated=False force=False\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> handing out existing connection\n",
      "DEBUG:neo4j:[#FA11]  C: RUN '\\nCALL apoc.meta.data()\\nYIELD label, other, elementType, type, property\\nWHERE type = \"RELATIONSHIP\" AND elementType = \"node\"\\nUNWIND other AS other_node\\nRETURN {start: label, type: property, end: toString(other_node)} AS output\\n' {} {'db': 'neo4j'}\n",
      "DEBUG:neo4j:[#FA11]  C: PULL {'n': 1000}\n",
      "DEBUG:neo4j:[#FA11]  S: SUCCESS {'t_first': 30, 'fields': ['output']}\n",
      "DEBUG:neo4j:[#FA11]  _: <CONNECTION> server state: READY > STREAMING\n",
      "DEBUG:neo4j:[#FA11]  S: RECORD * 1\n",
      "DEBUG:neo4j:[#FA11]  S: RECORD * 1\n",
      "DEBUG:neo4j:[#FA11]  S: RECORD * 1\n",
      "DEBUG:neo4j:[#FA11]  S: RECORD * 1\n",
      "DEBUG:neo4j:[#FA11]  S: RECORD * 1\n",
      "DEBUG:neo4j:[#FA11]  S: SUCCESS {'bookmark': 'FB:kcwQ6StP4FHeSWOIpT0EVLaCoBuQ', 'type': 'r', 't_last': 2, 'db': 'neo4j'}\n",
      "DEBUG:neo4j:[#FA11]  _: <CONNECTION> server state: STREAMING > READY\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> released bolt-84\n",
      "DEBUG:neo4j:[#0000]  _: <POOL> acquire direct connection, access_mode='WRITE', database='neo4j'\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> picked existing connection bolt-84\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> checked re_auth auth=None updated=False force=False\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> handing out existing connection\n",
      "DEBUG:neo4j:[#FA11]  C: RUN '\\n                CREATE CONSTRAINT IF NOT EXISTS FOR (n:Entity) REQUIRE n.id IS UNIQUE;\\n                ' {} {'db': 'neo4j'}\n",
      "DEBUG:neo4j:[#FA11]  C: PULL {'n': 1000}\n",
      "DEBUG:neo4j:[#FA11]  S: SUCCESS {'t_first': 3, 'fields': []}\n",
      "DEBUG:neo4j:[#FA11]  _: <CONNECTION> server state: READY > STREAMING\n",
      "DEBUG:neo4j:[#FA11]  S: SUCCESS {'bookmark': 'FB:kcwQ6StP4FHeSWOIpT0EVLaCoBuQ', 'type': 's', 't_last': 0, 'db': 'neo4j'}\n",
      "DEBUG:neo4j:[#FA11]  _: <CONNECTION> server state: STREAMING > READY\n",
      "DEBUG:neo4j:[#FA11]  _: <POOL> released bolt-84\n"
     ]
    },
    {
     "ename": "KeyError",
     "evalue": "'AZURE_OPENAI_API_KEY'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[7], line 5\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mllama_hub\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mllama_packs\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mneo4j_query_engine\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mbase\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Neo4jQueryEngineType\n\u001b[1;32m      4\u001b[0m \u001b[38;5;66;03m# create the pack\u001b[39;00m\n\u001b[0;32m----> 5\u001b[0m neo4j_pack \u001b[38;5;241m=\u001b[39m \u001b[43mNeo4jQueryEnginePack\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m      6\u001b[0m \u001b[43m  \u001b[49m\u001b[43musername\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43musername\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m      7\u001b[0m \u001b[43m  \u001b[49m\u001b[43mpassword\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mpassword\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m      8\u001b[0m \u001b[43m  \u001b[49m\u001b[43murl\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m      9\u001b[0m \u001b[43m  \u001b[49m\u001b[43mdatabase\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mdatabase\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m     10\u001b[0m \u001b[43m  \u001b[49m\u001b[43mdocs\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mdocuments\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m     11\u001b[0m \u001b[43m  \u001b[49m\u001b[43mquery_engine_type\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mNeo4jQueryEngineType\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mKG_KEYWORD\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m     12\u001b[0m \u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/AI_LLM/llm_notebooks/notebooks/neo4j_pack/base.py:60\u001b[0m, in \u001b[0;36mNeo4jQueryEnginePack.__init__\u001b[0;34m(self, username, password, url, database, docs, query_engine_type, **kwargs)\u001b[0m\n\u001b[1;32m     55\u001b[0m neo4j_storage_context \u001b[38;5;241m=\u001b[39m StorageContext\u001b[38;5;241m.\u001b[39mfrom_defaults(\n\u001b[1;32m     56\u001b[0m     graph_store\u001b[38;5;241m=\u001b[39mneo4j_graph_store\n\u001b[1;32m     57\u001b[0m )\n\u001b[1;32m     59\u001b[0m \u001b[38;5;66;03m# 使用 Auzre OpenAI 配置\u001b[39;00m\n\u001b[0;32m---> 60\u001b[0m api_key \u001b[38;5;241m=\u001b[39m \u001b[43mos\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43menviron\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mAZURE_OPENAI_API_KEY\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\n\u001b[1;32m     61\u001b[0m azure_endpoint \u001b[38;5;241m=\u001b[39m os\u001b[38;5;241m.\u001b[39menviron[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAZURE_OPENAI_ENDPOINT\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[1;32m     62\u001b[0m api_version \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m2023-07-01-preview\u001b[39m\u001b[38;5;124m\"\u001b[39m\n",
      "File \u001b[0;32m<frozen os>:679\u001b[0m, in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n",
      "\u001b[0;31mKeyError\u001b[0m: 'AZURE_OPENAI_API_KEY'"
     ]
    }
   ],
   "source": [
    "from llama_hub.llama_packs.neo4j_query_engine.base import Neo4jQueryEngineType\n",
    "\n",
    "\n",
    "# create the pack\n",
    "neo4j_pack = Neo4jQueryEnginePack(\n",
    "  username = username,\n",
    "  password = password,\n",
    "  url = url,\n",
    "  database = database,\n",
    "  docs = documents,\n",
    "  query_engine_type = Neo4jQueryEngineType.KG_KEYWORD,\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "2ViEkJinLLiH"
   },
   "source": [
    "## Run Pack"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 81
    },
    "id": "mn2DIWuX1XBR",
    "outputId": "67edb07d-2d7c-4c84-da60-01cca8ec7a64"
   },
   "outputs": [],
   "source": [
    "from IPython.display import Markdown\n",
    "\n",
    "response = neo4j_pack.run(\"Tell me about the benefits of paleo diet.\")\n",
    "display(Markdown(f\"<b>{response}</b>\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "a8JoNXXwL9_M"
   },
   "source": [
    "我们尝试使用KG混合查询引擎。请参见下面的代码。你可以通过替换 `Neo4jQueryEngineType` 枚举中的其他查询引擎类型来以类似的方式尝试任何其他查询引擎。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 133
    },
    "id": "vEzStIYvJa9S",
    "outputId": "95136bdf-68a7-4dd7-912b-ca4cd6d2fb23"
   },
   "outputs": [],
   "source": [
    "neo4j_pack = Neo4jQueryEnginePack(\n",
    "  username = username,\n",
    "  password = password,\n",
    "  url = url,\n",
    "  database = database,\n",
    "  docs = documents,\n",
    "  query_engine_type = Neo4jQueryEngineType.KG_HYBRID\n",
    ")\n",
    "\n",
    "response = neo4j_pack.run(\"Tell me about the benefits of paleo diet.\")\n",
    "display(Markdown(f\"<b>{response}</b>\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "XoK0BiKZDMaJ"
   },
   "source": [
    "## 知识图谱查询策略比较\n",
    "\n",
    "下表列出了7种查询引擎的详细信息，以及基于与NebulaGraph和LlamaIndex的实验得出的它们的优缺点，这在博客文章 [利用 LlamaIndex 浏览知识图谱的 7 种查询策略](https://www.toutiao.com/article/7317169514767008271/)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "DVr0XiFBGMY-"
   },
   "source": [
    "![知识图谱查询策略比较](https://p3-sign.toutiaoimg.com/tos-cn-i-6w9my0ksvp/ffa837ee967d46f9baaf28784b7ec0c0~noop.image?_iz=58558&from=article.pc_detail&lk3s=953192f4&x-expires=1704356130&x-signature=GXA885tOjv39mCKu1oftcWCcWtA%3D)"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "machine_shape": "hm",
   "provenance": []
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
